package org.jetlinks.pro.rule.engine.device;

import lombok.AllArgsConstructor;
import org.jetlinks.core.event.EventBus;
import org.jetlinks.rule.engine.api.RuleData;
import org.jetlinks.rule.engine.api.task.ExecutionContext;
import org.jetlinks.rule.engine.api.task.TaskExecutor;
import org.jetlinks.rule.engine.api.task.TaskExecutorProvider;
import org.jetlinks.rule.engine.defaults.FunctionTaskExecutor;
import org.reactivestreams.Publisher;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

@Component
@AllArgsConstructor
public class SceneRuleTaskExecutorProvider implements TaskExecutorProvider {

    private final EventBus eventBus;

    @Override
    public String getExecutor() {
        return "scene";
    }

    @Override
    public Mono<TaskExecutor> createTask(ExecutionContext context) {

        return Mono.just(new DeviceSceneTaskExecutor(context));
    }

    class DeviceSceneTaskExecutor extends FunctionTaskExecutor {

        private String id;

        private String name;

        public DeviceSceneTaskExecutor(ExecutionContext context) {
            super("场景联动", context);
            reload();
        }

        @Override
        public void reload() {
            this.id = (String) getContext().getJob().getConfiguration().get("id");
            this.name = (String) getContext().getJob().getConfiguration().get("name");
        }

        @Override
        protected Publisher<RuleData> apply(RuleData input) {
            Map<String, Object> data = new HashMap<>();
            data.put("sceneId", id);
            data.put("sceneName", name);
            data.put("executeTime", System.currentTimeMillis());

            input.acceptMap(data::putAll);

            return eventBus
                .publish(String.join("/", "scene", id), data)
                .thenReturn(context.newRuleData(input.newData(data)));
        }
    }
}
